/*
 * Copyrignt (c) xuzeshui.com. All Rights Reserved.
 * Author: Zeshui Xu<i@xuzeshui.com>
 * Created Time: 2015-12-10 16:46:09
 * Last Modified: 2015-12-17 20:51:10
 * File Name: xfile/statfile.go
 * Description:
 */
package xfile

import (
	"encoding/json"
	"fmt"
	"sync"

	"github.com/astaxie/beego"
	log "github.com/cihub/seelog"
)

const (
	PI_USER    string = "pp_user"
	PI_ACCOUNT string = "pp_account"
)

const (
	OP_INSERT string = "insert"
	OP_UPDATE string = "update"
	OP_DELETE string = "delete"
)

var (
	defaultPassportInfoMgr *PassportInfoMgr
)

type PassportInfoItem struct {
	Op        string      `json:"op"`
	TableName string      `json:"tablename"`
	Data      interface{} `json:"data"`
}

type PassportInfoMgr struct {
	rfw         map[string]*rollingFileWriter
	lock        *sync.RWMutex
	saveBaseDir string
}

func NewPassportInfoMgr(saveBaseDir string) *PassportInfoMgr {
	return &PassportInfoMgr{
		rfw:         make(map[string]*rollingFileWriter),
		lock:        new(sync.RWMutex),
		saveBaseDir: saveBaseDir,
	}
}

func (p *PassportInfoMgr) getPassportInfoFile(passportKey string) *rollingFileWriter {
	p.lock.RLock()
	if rw, ok := p.rfw[passportKey]; ok {
		p.lock.RUnlock()
		return rw
	} else {
		p.lock.RUnlock()
		p.lock.Lock()
		saveDir := fmt.Sprintf("%s/%s", p.saveBaseDir, passportKey)
		rw, _ := NewRollingFileWriter(saveDir, passportKey, 900)
		p.rfw[passportKey] = rw
		p.lock.Unlock()
		return rw
	}
}

func (p *PassportInfoMgr) SavePassportInfo(piItem *PassportInfoItem) {
	if piItem == nil || piItem.TableName == "" {
		return
	}
	rw := p.getPassportInfoFile(piItem.TableName)
	b, err := json.Marshal(piItem)
	if err != nil {
		return
	}
	rw.Write(b)
	rw.Write([]byte("\n"))
}

func (p *PassportInfoMgr) Stop() {
	p.lock.Lock()
	defer p.lock.Unlock()
	for tablename, rw := range p.rfw {
		rw.Close()
		log.Warnf("Stop PassportInfoMgr for %s", tablename)
		fmt.Printf("Stop PassportInfoMgr for %s", tablename)
	}
}

func GetPassportInfoMgr() *PassportInfoMgr {
	return defaultPassportInfoMgr
}

func init() {
	saveBaseDir := beego.AppConfig.DefaultString("passportinfo_save_dir", "../db_passport_info")
	defaultPassportInfoMgr = NewPassportInfoMgr(saveBaseDir)
}
